package com.ww.ll.builder;

import java.io.File;
import java.io.FileReader;

import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Version;

import com.ww.ll.LuceneBase;

public class DocBuilder extends LuceneBase {
	
	private static final Logger log = Logger.getLogger(DocBuilder.class);
	
	private void buildIndex() throws Exception{
		// 索引输出
		Directory indexDir = getIndexDir();
		IndexWriter iw = new IndexWriter(indexDir
			, new IndexWriterConfig(Version.LUCENE_40, getAnalyzer()));
		
		log.info("索引文档数：" + iw.numDocs());
		
		int count = 0;
		try{
			// 遍历所有文本文件
			File docDir = new File(getClassPathBase(), "doc");
			for(File docFile : docDir.listFiles()){
				// 索引一个文档
				// 用md5作为主键
				Term key = new Term(FIELD_NAME_KEY, computeMd5Str(docFile));
				//iw.deleteDocuments(key);
				iw.updateDocument(key, extractDoc(docFile));
				//iw.addDocument(extractDoc(docFile));
				iw.commit();
				count ++;
			}
		}finally{
			try{
				iw.close();
			}finally{
				if(IndexWriter.isLocked(indexDir))
					IndexWriter.unlock(indexDir);
			}
		}
		
		log.info("本次成功索引：" + count + "篇文档");
	}
	
	private Document extractDoc(File docFile) {
		try{
			Document doc = new Document();
			// 文件地址 原样保存
			doc.add(new StringField(FIELD_NAME_FS_PATH, docFile.toString(), Store.YES));
			// 文件名 原样保存
			doc.add(new StringField(FIELD_NAME_FS_NAME, docFile.getName(), Store.YES));
			// 内容
			doc.add(new TextField(FIELD_NAME_CONTENT, getAnalyzer().tokenStream(null, new FileReader(docFile))));
			// 以内容的md5为主键
			// new DerefBytesDocValuesField(name, bytes) 这种字段可以用来保存每个文件的一些原始文字信息  并且 如果多个文件包含相同的文字信息 那么储存时只会存一份 其他文件是只想储存的指针
			// StraightBytesDocValuesField 也可以保存文件的一些原始文字信息 但是 每个文件储存的数据都是独立的 因此适合一些唯一值保存 例如文档的md5 title等
			// doc.add(new StraightBytesDocValuesField(FIELD_NAME_KEY, computeMd5L(docFile)));
			doc.add(new StringField(FIELD_NAME_KEY, computeMd5Str(docFile), Store.NO));
			return doc;
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	
	
	public static void main(String[] args) throws Exception{
		DocBuilder db = new DocBuilder();
		db.buildIndex();
	}
	
	
}
